package org.vyana.model {

	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	
	import org.vyana.model.modules.*;
	import org.vyana.model.vo.ThemeModuleDescriptor;
	import org.vyana.model.vo.VyanaModuleDescriptor;
	
	public class VyanaModulesManager extends VyanaManager {
		
		protected var moduleDescriptors:Array = [];		
		
		function VyanaModulesManager() {
			
		}
		
		public function get loadedModules():Dictionary {
			var result:Dictionary = new Dictionary();
			
			enumModuleDescriptors(
				function (md:VyanaModuleDescriptor):Boolean {					
					if (md.isLoaded)						
						result[md.module.url] = md.module;					
					
					return false;
				}
			);
			
			return result;
		}
		
		public function registerModuleDescriptor(md:VyanaModuleDescriptor):void {
			
			moduleDescriptors.push(md);
			
			// Load Default modules
			if (md.isDefault)
				md.load();
			
		}
		
		public function get moduleDescriptorsList():Array {
			return moduleDescriptors;
		}
		
		public function set moduleDescriptorsList(value:*):void {
			var md:VyanaModuleDescriptor;

			moduleDescriptors = [];
			
			if (value is Array)
				for each (md in value)
					registerModuleDescriptor(md);
				
			
			if (value is XMLList)
				for each (var m:XML in value) {
									
					md = newModuleDescriptor(m);
					
					if (md) {
						registerModuleDescriptor(md);
						md = null;
					}	
				}			

			new VyanaModuleEvent(VyanaModuleEvent.MODULE_DESCRIPTORS_LIST_SET, this).dispatch();
		}
		
		public function getThemeModuleDescriptor(themeId:String):ThemeModuleDescriptor {
			var result:ThemeModuleDescriptor;
			
			enumModuleDescriptors(
				function (d:VyanaModuleDescriptor):void {
					if (d is ThemeModuleDescriptor && ThemeModuleDescriptor(d).id == themeId)
						result = d as ThemeModuleDescriptor;
				}
			);
			
			return result;
		}		
		
		public function enumLoadedModules(visitorFunction:Function):void {
			
			for each (var m:* in loadedModules)
				if (visitorFunction(m)) break;
			
		}
		
		public function enumModuleDescriptors(visitorFunction:Function):void {
			
			for each (var md:VyanaModuleDescriptor in moduleDescriptors)				
				if (visitorFunction(md)) break;
			
		}
		
		public function enumResourceModules(visitor:Function):void {
			
			enumLoadedModules(
				function (m:VyanaModule):void {
					if (m is BaseResourceModule)
						visitor(m);
				}
			);
			
		}
		
		public function loadEmbedModule(moduleClass:Class):void {
			var md:VyanaModuleDescriptor = new VyanaModuleDescriptor('', '', getQualifiedClassName(this));
			md.load(new moduleClass() as ByteArray);			
		}		
		
		protected function newModuleDescriptor(m:XML):VyanaModuleDescriptor {
			return new VyanaModuleDescriptor(m.@type, m.@id, m.@url, m.@default == 'true');
		}
	
	}
}